@robert-hh Another variant for measuring, which determines the difference between a minimal and maximal value over a window of samples, which should be at least a period of the signal to be tested, e.g. 20 ms for a 50Hz net. More simple than the last example, and immune to offset drifts. Still, the ADC is bad. The noise is a little bit lower if WiFi is switched off, but that only matters at small signals. # import math import array from machine import ADC, Timer, idle samples = 600 freq = 50 _BUFFERSIZE = const(64) # # acquire ADC values at a fixed rate/s, which is given in # the constructor. The second argument is the size # of a ringbuffer, the third a string with the Pin name # class Acquire: def __init__(self, samples, buffersize, pin): self.put = 0 self.get = 0 self.buffersize = buffersize self.buffer = array.array("h", 0 for _ in range(self.buffersize)) self.adc = ADC(bits=9) self.apin = self.adc.channel(pin=pin, attn=ADC.ATTN_11DB) self._alarm = Timer.Alarm(self.read_adc, 1/samples, periodic=True) def stop(self): self._alarm.cancel() def read_adc(self, alarm): self.buffer[self.put] = self.apin.value() self.put = (self.put + 1) % self.buffersize def next(self, period): vmin = 4096 vmax = 0 for _ in range(period): while self.get == self.put: idle() # calculate the moving average over the last three values: value = (self.buffer[self.get] + self.buffer[(self.get - 1) % self.buffersize] + self.buffer[(self.get - 2) % self.buffersize]) / 3 vmin = min(value, vmin) vmax = max(value, vmax) self.get = (self.get + 1) % self.buffersize return vmax - vmin # # calculate a moving average # The constructors argument is the window size # class Average: def __init__(self, size): self.size = size self.buffer = array.array("f", 0.0 for _ in range (size)) self.put = 0 self.sum = 0.0 def avg(self, value): self.sum -= self.buffer[self.put] self.buffer[self.put] = value self.put = (self.put + 1) % self.size self.sum += value return self.sum / self.size def run(noise=1.2): acq = Acquire(samples, _BUFFERSIZE, 'P20') avg_res = Average(freq) noise_sq = noise * noise try: i = 0 while True: res = avg_res.avg(acq.next(samples/freq)) i += 1 if i == freq: # remove the noise floor res = math.sqrt(abs(res*res - noise_sq)) print("{:6.2f} ".format(res/20.2)) i = 0 except KeyboardInterrupt: acq.stop() print("Handler stopped") run()